<?php

namespace app\admin\controller\scanwork;

use app\common\controller\Backend;
use think\Db;
use Exception;
use think\exception\PDOException;
use think\exception\ValidateException;

/**
 * 入库管理
 *
 * @icon fa fa-warehouse
 * @remark 管理所有类型的入库业务，包括采购入库、生产入库、调拨入库等
 */
class InventoryManagement extends Backend
{
    /**
     * InventoryManagement模型对象
     * @var \app\admin\model\scanwork\InventoryManagement
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\scanwork\InventoryManagement;
        
        // 获取仓库列表
        $warehouseList = \app\admin\model\scanwork\Warehouse::where('status', 1)->column('warehouse_name', 'id');
        $this->view->assign("warehouseList", $warehouseList);
        
        // 获取供应商列表
        $supplierList = \app\admin\model\scanwork\Supplier::where('status', 1)->column('name', 'id');
        $this->view->assign("supplierList", $supplierList);
    }

    /**
     * 入库单列表
     */
    public function index()
    {
        // 设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();

            $list = Db::name('scanwork_purchase_inbound')
                ->alias('pi')
                ->join('scanwork_supplier s', 'pi.supplier_id = s.id', 'left')
                ->join('scanwork_warehouse w', 'pi.warehouse_id = w.id', 'left')
                ->join('admin a', 'pi.inbound_user_id = a.id', 'left')
                ->field('pi.*, s.name as supplier_name, w.warehouse_name, a.username as operator_name')
                ->where($where)
                ->order($sort, $order)
                ->limit($offset, $limit)
                ->select();

            $total = Db::name('scanwork_purchase_inbound')
                ->alias('pi')
                ->join('scanwork_supplier s', 'pi.supplier_id = s.id', 'left')
                ->where($where)
                ->count();

            $result = array("total" => $total, "rows" => $list);
            return json($result);
        }
        return $this->view->fetch();
    }

    /**
     * 入库审核
     */
    public function audit()
    {
        if ($this->request->isPost()) {
            $ids = $this->request->post('ids');
            $auditResult = $this->request->post('audit_result'); // approve, reject
            $auditRemark = $this->request->post('audit_remark');
            
            if (empty($ids)) {
                $this->error('请选择要审核的入库单');
            }
            
            if (empty($auditResult)) {
                $this->error('请选择审核结果');
            }

            Db::startTrans();
            try {
                $inbounds = Db::name('scanwork_purchase_inbound')
                    ->where('id', 'in', $ids)
                    ->where('status', 1) // 待入库
                    ->select();

                if (empty($inbounds)) {
                    throw new Exception('没有找到待审核的入库单');
                }

                foreach ($inbounds as $inbound) {
                    if ($auditResult == 'approve') {
                        // 审核通过，更新状态为已入库
                        Db::name('scanwork_purchase_inbound')
                            ->where('id', $inbound['id'])
                            ->update([
                                'status' => 2, // 已入库
                                'inbound_user_id' => $this->auth->id,
                                'updatetime' => time()
                            ]);
                        
                        // 更新物料库存
                        $this->updateMaterialStock($inbound['id']);
                        
                    } elseif ($auditResult == 'reject') {
                        // 审核拒绝，更新状态为已取消
                        Db::name('scanwork_purchase_inbound')
                            ->where('id', $inbound['id'])
                            ->update([
                                'status' => 3, // 已取消
                                'updatetime' => time()
                            ]);
                    }
                }

                Db::commit();
                $this->success('审核完成');
                
            } catch (Exception $e) {
                Db::rollback();
                $this->error('审核失败：' . $e->getMessage());
            }
        }

        // 获取待审核的入库单
        $inbounds = Db::name('scanwork_purchase_inbound')
            ->alias('pi')
            ->join('scanwork_supplier s', 'pi.supplier_id = s.id', 'left')
            ->join('scanwork_warehouse w', 'pi.warehouse_id = w.id', 'left')
            ->field('pi.*, s.name as supplier_name, w.warehouse_name')
            ->where('pi.status', 1) // 待入库
            ->select();

        $this->view->assign('inbounds', $inbounds);
        return $this->view->fetch();
    }

    /**
     * 更新物料库存
     */
    private function updateMaterialStock($inboundId)
    {
        // 获取入库明细
        $items = Db::name('scanwork_purchase_inbound_item')
            ->where('inbound_id', $inboundId)
            ->select();

        foreach ($items as $item) {
            // 更新物料库存
            $material = Db::name('scanwork_material')->find($item['material_id']);
            if ($material) {
                $newStock = $material['stock'] + $item['actual_quantity'];
                Db::name('scanwork_material')
                    ->where('id', $item['material_id'])
                    ->update(['stock' => $newStock]);
                
                // 记录库存变动
                Db::name('scanwork_inventory_record')->insert([
                    'material_id' => $item['material_id'],
                    'inbound_id' => $inboundId,
                    'type' => 1, // 入库
                    'quantity' => $item['actual_quantity'],
                    'before_stock' => $material['stock'],
                    'after_stock' => $newStock,
                    'unit_price' => $item['unit_price'],
                    'batch_no' => $item['batch_no'],
                    'operator_id' => $this->auth->id,
                    'operate_time' => time(),
                    'createtime' => time()
                ]);
            }
        }
    }

    /**
     * 入库统计
     */
    public function statistics()
    {
        if ($this->request->isAjax()) {
            $startDate = $this->request->param('start_date', date('Y-m-01'));
            $endDate = $this->request->param('end_date', date('Y-m-d'));
            $supplierId = $this->request->param('supplier_id');
            $warehouseId = $this->request->param('warehouse_id');

            $where = [
                ['pi.status', '=', 2], // 已入库
                ['pi.inbound_date', 'between', [strtotime($startDate), strtotime($endDate . ' 23:59:59')]]
            ];

            if ($supplierId) {
                $where[] = ['pi.supplier_id', '=', $supplierId];
            }
            if ($warehouseId) {
                $where[] = ['pi.warehouse_id', '=', $warehouseId];
            }

            // 按供应商统计
            $supplierStats = Db::name('scanwork_purchase_inbound')
                ->alias('pi')
                ->join('scanwork_supplier s', 'pi.supplier_id = s.id', 'left')
                ->field('pi.supplier_id, s.name as supplier_name, COUNT(*) as inbound_count, SUM(pi.total_amount) as total_amount')
                ->where($where)
                ->group('pi.supplier_id')
                ->order('total_amount', 'desc')
                ->select();

            // 按仓库统计
            $warehouseStats = Db::name('scanwork_purchase_inbound')
                ->alias('pi')
                ->join('scanwork_warehouse w', 'pi.warehouse_id = w.id', 'left')
                ->field('pi.warehouse_id, w.warehouse_name, COUNT(*) as inbound_count, SUM(pi.total_amount) as total_amount')
                ->where($where)
                ->group('pi.warehouse_id')
                ->order('total_amount', 'desc')
                ->select();

            // 按日期统计
            $dailyStats = Db::name('scanwork_purchase_inbound')
                ->field('FROM_UNIXTIME(inbound_date, "%Y-%m-%d") as date, COUNT(*) as inbound_count, SUM(total_amount) as total_amount')
                ->where($where)
                ->group('FROM_UNIXTIME(inbound_date, "%Y-%m-%d")')
                ->order('date', 'asc')
                ->select();

            // 总体统计
            $totalStats = Db::name('scanwork_purchase_inbound')
                ->field('COUNT(*) as total_count, SUM(total_amount) as total_amount, AVG(total_amount) as avg_amount')
                ->where($where)
                ->find();

            $result = [
                'supplier_stats' => $supplierStats,
                'warehouse_stats' => $warehouseStats,
                'daily_stats' => $dailyStats,
                'total_stats' => $totalStats
            ];

            $this->success('获取成功', '', $result);
        }
        return $this->view->fetch();
    }

    /**
     * 入库明细
     */
    public function detail($ids = null)
    {
        $inbound = Db::name('scanwork_purchase_inbound')
            ->alias('pi')
            ->join('scanwork_supplier s', 'pi.supplier_id = s.id', 'left')
            ->join('scanwork_warehouse w', 'pi.warehouse_id = w.id', 'left')
            ->join('admin a', 'pi.inbound_user_id = a.id', 'left')
            ->field('pi.*, s.name as supplier_name, w.warehouse_name, a.username as operator_name')
            ->where('pi.id', $ids)
            ->find();

        if (!$inbound) {
            $this->error('入库单不存在');
        }

        // 获取入库明细
        $items = Db::name('scanwork_purchase_inbound_item')
            ->alias('pii')
            ->join('scanwork_material m', 'pii.material_id = m.id', 'left')
            ->field('pii.*, m.name as material_name, m.code as material_code, m.unit')
            ->where('pii.inbound_id', $ids)
            ->select();

        $inbound['items'] = $items;

        $this->view->assign('inbound', $inbound);
        return $this->view->fetch();
    }

    /**
     * 批量操作
     */
    public function batchOperation()
    {
        if ($this->request->isPost()) {
            $ids = $this->request->post('ids');
            $operation = $this->request->post('operation');
            
            if (empty($ids)) {
                $this->error('请选择要操作的入库单');
            }
            
            if (empty($operation)) {
                $this->error('请选择操作类型');
            }

            Db::startTrans();
            try {
                switch ($operation) {
                    case 'approve':
                        // 批量审核通过
                        Db::name('scanwork_purchase_inbound')
                            ->where('id', 'in', $ids)
                            ->where('status', 1)
                            ->update([
                                'status' => 2,
                                'inbound_user_id' => $this->auth->id,
                                'updatetime' => time()
                            ]);
                        break;
                        
                    case 'reject':
                        // 批量审核拒绝
                        Db::name('scanwork_purchase_inbound')
                            ->where('id', 'in', $ids)
                            ->where('status', 1)
                            ->update([
                                'status' => 3,
                                'updatetime' => time()
                            ]);
                        break;
                        
                    case 'delete':
                        // 批量删除（只能删除草稿状态的）
                        Db::name('scanwork_purchase_inbound')
                            ->where('id', 'in', $ids)
                            ->where('status', 0)
                            ->delete();
                        break;
                        
                    default:
                        throw new Exception('不支持的操作类型');
                }

                Db::commit();
                $this->success('批量操作完成');
                
            } catch (Exception $e) {
                Db::rollback();
                $this->error('操作失败：' . $e->getMessage());
            }
        }
    }

    /**
     * 入库报表
     */
    public function report()
    {
        if ($this->request->isAjax()) {
            $reportType = $this->request->param('report_type', 'summary');
            $startDate = $this->request->param('start_date', date('Y-m-01'));
            $endDate = $this->request->param('end_date', date('Y-m-d'));

            $where = [
                ['pi.status', '=', 2], // 已入库
                ['pi.inbound_date', 'between', [strtotime($startDate), strtotime($endDate . ' 23:59:59')]]
            ];

            switch ($reportType) {
                case 'summary':
                    // 汇总报表
                    $data = Db::name('scanwork_purchase_inbound')
                        ->alias('pi')
                        ->join('scanwork_supplier s', 'pi.supplier_id = s.id', 'left')
                        ->field('pi.*, s.name as supplier_name')
                        ->where($where)
                        ->order('pi.inbound_date', 'desc')
                        ->select();
                    break;
                    
                case 'material':
                    // 物料入库报表
                    $data = Db::name('scanwork_purchase_inbound_item')
                        ->alias('pii')
                        ->join('scanwork_purchase_inbound pi', 'pii.inbound_id = pi.id', 'left')
                        ->join('scanwork_material m', 'pii.material_id = m.id', 'left')
                        ->join('scanwork_supplier s', 'pi.supplier_id = s.id', 'left')
                        ->field('pii.*, pi.inbound_no, pi.inbound_date, m.name as material_name, m.code as material_code, s.name as supplier_name')
                        ->where($where)
                        ->order('pi.inbound_date', 'desc')
                        ->select();
                    break;
                    
                default:
                    $data = [];
            }

            $this->success('获取成功', '', $data);
        }
        return $this->view->fetch();
    }
}
